import pickle

import pandas as pd
from numpy import concatenate
from pandas import DataFrame, concat
# import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler


# convert series to supervised learning
def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
    n_vars = 1 if type(data) is list else data.shape[1]
    df = DataFrame(data)
    cols, names = list(), list()
    # input sequence (t-n, ... t-1)
    for i in range(n_in, 0, -1):
        cols.append(df.shift(i))
        names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)]
    # forecast sequence (t, t+1, ... t+n)
    for i in range(0, n_out):
        cols.append(df.shift(-i))
        if i == 0:
            names += [('var%d(t)' % (j+1)) for j in range(n_vars)]
        else:
            names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)]
    # put it all together
    agg = concat(cols, axis=1)
    agg.columns = names
    # drop rows with NaN values
    if dropnan:
        agg.dropna(inplace=True)
    return agg

def data_cut(dataset):
    # specify columns to plot
    dataset.drop(dataset.columns[[0]], axis=1, inplace=True)
    values = dataset.values.astype('float32')
    return values

def data_process(scaled):
    # frame as supervised learning
    reframed = series_to_supervised(scaled, 1, 1)
    # drop columns we don't want to predict
    reframed.drop(reframed.columns[[4,5,6]], axis=1, inplace=True)

    values = reframed.values
    n_train_hours = 1000
    # train = values[:n_train_hours, :]
    test = values[n_train_hours:, :]
    # split into input and outputs
    # train_X, train_y = train[:, :-1], train[:, -1]
    test_X, test_y = test[:, :-1], test[:, -1]
    # reshape input to be 3D [samples, timesteps, features]
    # train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
    test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
    return test_X, test_y

if __name__ =="__main__":
    data = pd.read_excel('Mul-LSTM_data.xlsx')
    values = data_cut(data)

    # normalize features
    scaler = MinMaxScaler(feature_range=(0, 1))
    scaled = scaler.fit_transform(values)

    # scaled = values
    test_X, test_y = data_process(scaled)

    # load the saved model
    with open('Mul-LSTM.pkl', 'rb') as f:
        model = pickle.load(f)

    # make a prediction
    yhat = model.predict(test_X)

    # invert scaling for forecast
    test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
    inv_yhat = concatenate((test_X[:,[0,1,2]], yhat), axis=1)
    inv_yhat = scaler.inverse_transform(inv_yhat)[:,-1].reshape(-1,1)

    # invert scaling for actual
    test_y = test_y.reshape((len(test_y), 1))
    inv_y = concatenate((test_X[:,[0,1,2]], test_y), axis=1)
    inv_y = scaler.inverse_transform(inv_y)[:,-1].reshape(-1,1)
    '''
    time = [i for i in range(len(inv_y))]
    plt.clf()
    plt.title("Test Set")
    plt.xlabel('Timestep')
    plt.ylabel('Predictions/Actual')
    plt.rcParams['figure.figsize'] = [30, 10]
    plt.plot(time, inv_y, label='Actual Load',linewidth=1)
    plt.plot(time,inv_yhat, label='Predicted Load',linestyle='dashed',linewidth=1)
    plt.legend()
    plt.savefig('predicted.png')
    plt.show()
    '''
    # 输出预测值
    print('Predict:', inv_yhat)
